<template>
  <div class="chat_operate flex p-16-24">
    <div class="chat_operate_textarea">
      <!-- @visible-change="visibleChange" -->
      <el-dropdown
        ref="dropdown"
        trigger="hover"
        placement="top-start"
        :popper-class="'res-dropdown-menu'"
      >
        <el-input
          ref="quickInputRef"
          v-model="inputValue"
          type="textarea"
          :placeholder="'请输入问题，Ctrl+Enter 换行'"
          :maxlength="100000"
          :autosize="{ minRows: 1, maxRows: 4 }"
          @keydown.enter="handleKeyDown"
        />
        <template #dropdown>
          <el-dropdown-menu v-for="(item, index) in formatSearchList"  :key="index">
            <div class="grouped-title">{{ item.dataSetName  }}</div>
            <el-dropdown-item v-for="(k,i) in item.items" :key="i" @click="handleSelectItem(k)">
              <el-tag v-if="k.schemaElementType" :type="SEMANTIC_TYPE_MAP_COLOR[k.schemaElementType as keyof typeof SEMANTIC_TYPE_MAP]" style="margin-right: 8px;">
                {{ SEMANTIC_TYPE_MAP[k.schemaElementType as keyof typeof SEMANTIC_TYPE_MAP] }}
              </el-tag>
              {{ k.subRecommend }} 
            </el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
      <el-button
        text
        :class="['sent-button', isDisabled && 'disabled-sent-button']"
        @click="sendChatHandle(inputValue)"
        :disabled="isDisabled"
      >
        <img src="@/assets/icon_send.svg" alt="" />
      </el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import type { DropdownInstance } from 'element-plus'
import ChatBi from '@/api/chatbi'
import useStore from '@/stores'
import bus from '@/bus'
import { debounce } from 'lodash-es'
import { SEMANTIC_TYPE_MAP, SEMANTIC_TYPE_MAP_COLOR } from '@/enums/chatbi'

const { chatbi } = useStore()
const inputValue = ref('')
const sendData = ref<any>({
  agentId: '',
  chatId: '',
  queryText: '',
  queryId: '',
  parseId: ''
})
let eventSource: any = null

const dropdown = ref<DropdownInstance>()
const isDisabled = ref(false)
const searchList = ref([])
const activeLoadding = ref(false)
const quickInputRef = ref()

const formatSearchList = computed(() => {
  if(!searchList.value.length){
    return []
  }
  const groupedData = searchList.value.reduce((acc: any, item: any) => {
    const key = item.dataSetName
    ;(acc[key] || (acc[key] = [])).push(item)
    return acc
  }, {})

  const groupedArray: any = Object.entries(groupedData).map(([name, items]) => ({
    dataSetName: name,
    items
  }))
  return groupedArray
})

/** 防抖搜索 */
const debouncedChatQuerySearch = debounce(chatQuerySearch, 300)

function showClick() {
  const dropdownInstance = dropdown.value
  if (!dropdownInstance) {
    console.warn('Dropdown instance is not available.')
    return
  }

  nextTick(() => {
    try {
      dropdownInstance.handleOpen()
    } catch (error) {
      console.error('Failed to open dropdown:', error)
    }
  })
}

function hidenClick() {
  if (!dropdown.value) return
  nextTick(() => {
    dropdown.value?.handleClose()
  })
}



function handleSelectItem(item: any) {
  activeLoadding.value = true
  inputValue.value = item.recommend
  searchList.value = [];
  setTimeout(() => {
    activeLoadding.value = false
  }, 500)

  // 主动让输入框获取焦点
  nextTick(() => {
    const textarea = quickInputRef.value?.textarea as HTMLTextAreaElement
    if (textarea) {
      textarea.focus()
    }
  })
}

// const chatItem = {
//   queryText: "1212", // 输入框的值
//   questionId: 317, // 当前对话问答的id
//   queryResult: {
//     chatContext: {
//       properties: {
//         thought:'' // 意图理解
//       }
//     },
//     queryColumns:[], // 表格动态列
//     queryResults: [], // 表格数据
//     textSummary: '', // 数据解读
//   }
// }

function handelCreateQuestionId(agentId: any, chatId: any, queryText: any) {
  // 第一步创建queryId
  ChatBi.createQuestionId({
    isInsight: false,
    isSearch: false,
    agentId,
    chatId,
    queryText
  })
    .then((res) => {
      sendData.value.queryId = res.data
      chatbi.setChatList([
        {
          queryText, // 输入框的值
          questionId: res.data, // 当前对话问答的id
          parseInfos: [],
          queryResult: {
            chatContext: {
              properties: {
                thought: '' // 意图理解
              }
            },
            queryColumns: [], // 表格动态列
            queryResults: [], // 表格数据
            textSummary: '' // 数据解读
          },
          pending: true, // 是否正在加载中
          tylj_pending: true // 意图理解加载中
        }
      ])
      initEventSource(agentId, chatId, queryText, res.data)
    })
    .catch((err: any) => {
      console.log(err)
    })
    .finally(() => {
      inputValue.value = ''
    })
}

function initEventSource(agentId: any, chatId: any, queryText: any, queryId: any) {
  // 第二步获取流数据
  eventSource = new EventSource(getUrl(agentId, chatId, queryId, queryText))
  eventSource.onopen = () => {
    console.log('[ eventSource-onopen ]')
  }
  eventSource.addEventListener('msg', (event: any) => {
    const { data } = event
    if (!data) {
      return
    }
    chatbi.updateChatSummaryWithStream(
      queryId,
      data,
      'queryResult.chatContext.properties.thought',
      true
    )
  })
  eventSource.onerror = (error: any) => {
    console.log('[ eventSource-error ]', error)
    eventSource && eventSource.close()
    handelQueryGetParse(agentId, chatId, queryText, queryId)
  }
  eventSource.addEventListener('complete', () => {
    console.log('[ eventSource-complete ]')
    eventSource && eventSource.close()
    handelQueryGetParse(agentId, chatId, queryText, queryId)
  })
}

function handelQueryGetParse(agentId: any, chatId: any, queryText: any, queryId: any) {
  // 第三部获取parseId
  ChatBi.queryGetParse(queryId)
    .then((res) => {
      // const parseId = res.data.parseInfo.id;
      // sendData.value.parseId = parseId
      // const isWidget = res.data.parseInfo.queryMode === 'CHART'
      // const parseInfo = res.data.parseInfo
      // chatbi.updateChatSummaryWithStream(queryId, parseInfo, 'parseInfos', true)
      // if (isWidget) {
      //   console.log('isWidget')
      //   chatbi.updateChatSummaryWithStream(queryId, false, 'pending', true)
      //   isDisabled.value = false
      // } else {
      //   handelQueryExecute(agentId, chatId, queryText, queryId, parseId)
      // }


      /*  2025-07-02 数据结果发生改变 */
      const parseInfoArr = res.data.parseInfos;
      if (Array.isArray(parseInfoArr) && parseInfoArr.length) {
        const parseInfo = parseInfoArr[0]
        const parseId = parseInfo.id;
        sendData.value.parseId = parseId
        const isWidget = parseInfo.queryMode === 'CHART'
        chatbi.updateChatSummaryWithStream(queryId, parseInfo, 'parseInfos', true)
        if (isWidget) {
          console.log('isWidget')
          chatbi.updateChatSummaryWithStream(queryId, false, 'pending', true)
          isDisabled.value = false
        } else {
          handelQueryExecute(agentId, chatId, queryText, queryId, parseId)
        }
      }
    })
    .catch((err) => {
      console.log(err)
      chatbi.updateChatSummaryWithStream(queryId, false, 'pending', false)
      chatbi.updateChatSummaryWithStream(queryId, false, 'tylj_pending', false)
      /* 查询报错 */ 
      chatbi.updateChatSummaryWithStream(queryId, false, 'parseInfos', false)
      isDisabled.value = false
    })
}

function handelQueryExecute(agentId: any, chatId: any, queryText: any, queryId: any, parseId: any) {
  // 第四部执行query-execute
  ChatBi.queryExecute({ agentId, chatId, queryText, queryId, parseId })
    .then((res: any) => {
      const { queryColumns, queryResults, chatContext } = res.data
      chatbi.updateChatSummaryWithStream(
        queryId,
        chatContext.properties.thought,
        'queryResult.chatContext.properties.thought',
        false
      )
      chatbi.updateChatSummaryWithStream(
        queryId,
        queryColumns,
        'queryResult.queryColumns',
        false
      )
      chatbi.updateChatSummaryWithStream(
        queryId,
        queryResults,
        'queryResult.queryResults',
        false
      )
      initEventSource1(agentId, chatId, queryText, queryId, parseId)
    })
    .catch((err: any) => {
      console.log(err)
    })
}

// 第五部获取对话历史

// 第六步 获取数据解流数据  aibi/api/chat/query/analyze
function initEventSource1(agentId: any, chatId: any, queryText: any, queryId: any, parseId: any) {
  console.log(agentId, chatId, queryText, queryId, parseId)
  const token = localStorage.getItem('token')
  const url =
    window.location.origin +
    `/aibi/api/chat/query/analyze?queryId=${queryId}&chatId=${chatId}&agentId=${agentId}&token=${token}`
  eventSource = new EventSource(url)
  eventSource.onopen = () => {
    console.log('[ eventSource-onopen ]')
  }
  eventSource.addEventListener('msg', (event: any) => {
    const { data } = event
    if (!data) {
      return
    }
    // 更新数据解读
    chatbi.updateChatSummaryWithStream(
      queryId,
      data,
      'queryResult.textSummary',
      true
    )
  })
  eventSource.onerror = (error: any) => {
    console.log('[ eventSource-error ]', error)
    eventSource && eventSource.close()
    isDisabled.value = false
    chatbi.updateChatSummaryWithStream(queryId, false, 'pending', false)
  }
}

function getUrl(agentId: any, chatId: any, queryId: any, queryText: any) {
  const fileIds = ''
  const token = localStorage.getItem('token')
  return (
    window.location.origin +
    `/aibi/api/chat/query/parse?queryId=${queryId}&queryText=${queryText}&chatId=${chatId}&agentId=${agentId}&fileIds=${fileIds}&token=${token}`
  )
}

function handleKeyDown(event: KeyboardEvent) {
  if (event.ctrlKey || event.metaKey) {
    // Ctrl/Cmd + Enter：插入换行符
    event.preventDefault(); // 阻止默认行为（防止触发发送）
    const target = event.target as HTMLTextAreaElement;
    const { selectionStart, selectionEnd } = target;

    // 插入换行符到光标位置
    inputValue.value =
      inputValue.value.substring(0, selectionStart) +
      '\n' +
      inputValue.value.substring(selectionEnd);

    // 设置光标位置到换行后的位置
    nextTick(() => {
      const textarea = quickInputRef.value?.textarea as HTMLTextAreaElement;
      if (textarea) {
        textarea.focus();
        textarea.setSelectionRange(selectionStart + 1, selectionStart + 1);
      }
    });
  } else {
    // 单独 Enter：发送消息
    event.preventDefault(); // 防止默认换行
    sendChatHandle(inputValue.value);
  }
}

function sendChatHandle(msg: string) {
  if (!msg && typeof msg !== 'string') {
    console.warn(`[输入的内容错误] ${msg}`)
    return
  }
  if (isDisabled.value) {
    return
  }

  bus.emit('scrollToAuto', true); // 滚动到底部
  
  isDisabled.value = true
  const locaAgentId = localStorage.getItem('agentId')
  const locaChatId = localStorage.getItem('chatId')
  sendData.value.agentId = Number(locaAgentId)
  sendData.value.chatId = Number(locaChatId)
  sendData.value.queryText = msg
  handelCreateQuestionId(locaAgentId, locaChatId, msg)
}

function chatQuerySearch(queryText: any) {
  const chatId = localStorage.getItem('chatId')
  const agentId = localStorage.getItem('agentId')
  searchList.value = []
  ChatBi.querySearch({ agentId: Number(agentId), chatId: Number(chatId), queryText })
    .then((res) => {
      if (res.data) {
        searchList.value = res.data
        res.data.length ? showClick() : hidenClick()
      }
    })
    .finally(() => {})
}

function chatIdUpdate(chatId: any){
  // console.log(`[ bus-chatid-update ]= ${chatId}`)
  isDisabled.value = false
}

watch(
  () => inputValue.value,
  (newVal) => {
    if (newVal &&  !activeLoadding.value) {
      debouncedChatQuerySearch(newVal)
    } else {
      searchList.value = []
    }
  }
)

watch(
  () => searchList.value,
  (newVal) => {
    if(newVal.length && inputValue.value.length === 0 ){
      searchList.value = []
    }
  }
)

onMounted(() => {
  // bus.on('send-msg', (msg: string) => {
  //   sendChatHandle(msg)
  // })

  bus.on('bus-chatid-update', chatIdUpdate)
})

onBeforeUnmount(() => {
  if (eventSource) {
    eventSource.close()
  }
  bus.off('bus-chatid-update', chatIdUpdate)
})

defineExpose({ sendChatHandle })

</script>

<style lang="scss" scoped>
.chat_operate {
  background: #f3f7f9;
  position: relative;
  width: 100%;
  box-sizing: border-box;
  z-index: 10;
  &_textarea {
    box-shadow: 0 6px 24px #1f232914;
    background-color: #fff;
    border-radius: 8px;
    border: 1px solid #ffffff;
    box-sizing: border-box;
    width: 100%;
    position: relative;
    .sent-button {
      position: absolute;
      right: 12px;
      top: 50%;
      margin-top: -16px;
      max-height: none;
      background: #3067ef !important;
      padding: 8px !important;
      border-radius: 8px !important;
    }
    .disabled-sent-button {
      background-color: #dedede !important;
    }
  }
  :deep(.el-textarea__inner) {
    border-radius: 8px !important;
    box-shadow: none;
    resize: none;
    padding: 12px 66px 12px 16px;
    box-sizing: border-box;
  }

  :deep(.el-textarea__inner):focus {
    box-shadow: 0 0 0 1px var(--el-input-focus-border-color) inset !important;
  }

  :deep(.el-dropdown) {
    width: calc(100% - 60px);
  }
}

.grouped-title{
  padding: 6px 20px;
  font-size: 16px;
  font-weight: 500;
}
</style>
